from django import forms
from django.db import models

from modelcluster.fields import ParentalKey, ParentalManyToManyField
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase

from wagtail.models import Page, Orderable
from wagtail.fields import RichTextField
from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel
from wagtail.search import index
from wagtail.snippets.models import register_snippet

from wagtailmarkdown.fields import MarkdownField
from wagtailmarkdown.blocks import MarkdownBlock

RICHTEXT_BLOCKTYPES = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol']
RICHTEXT_INLINESTYLES = ['bold', 'italic']

ALL_RICHTEXT_FEATURES = [
	'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'bold', 'italic', 'link',
	'hr', 'document-link', 'image', 'embed', 'code', 'superscript', 'subscript',
	'strikethrough', 'blockquote'
	]

# Create your models here.

@register_snippet
class Authors(models.Model):
    name = models.CharField(max_length=255)
    author_image = models.ForeignKey(
        'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+'
    )

    panels = [
        FieldPanel('name'),
        FieldPanel('author_image'),
    ]

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'authors'


class BlogPageTag(TaggedItemBase):
	content_object = ParentalKey(
		'BlogPage',
		related_name='tagged_items',
		on_delete=models.CASCADE
	)

class MarkdownBlogPageTag(TaggedItemBase):
	content_object = ParentalKey(
		'MarkdownBlogPage',
		related_name='tagged_items',
		on_delete=models.CASCADE
	)

class BlogIndexPage(Page):
	intro = RichTextField(blank=True)

	content_panels = Page.content_panels + [
		FieldPanel('intro', classname="full")
	]

	def get_context(self, request, *args, **kwargs):
		# Update context to include only published posts, ordered by reverse-chron
		context = super().get_context(request)
		blogpages = self.get_children().live().order_by('-first_published_at')
		context['blogpages'] = blogpages
		return context

class BlogPage(Page):
	date = models.DateField("Post date")
	intro = models.CharField(max_length=250)
	body = RichTextField(blank=True, features = ALL_RICHTEXT_FEATURES)
	authors = ParentalManyToManyField('blog.authors', blank=True)
	tags = ClusterTaggableManager(through=BlogPageTag, blank=True)

	def main_image(self):
		gallery_item = self.gallery_image.first()
		if gallery_item:
			return gallery_item.image
		else:
			return None

	search_fields = Page.search_fields + [
		index.SearchField('intro'),
		index.SearchField('body'),
	]

	content_panels = Page.content_panels + [
		MultiFieldPanel([
			FieldPanel('date'),
			FieldPanel('authors', widget=forms.CheckboxSelectMultiple),
			FieldPanel('tags'),
		], heading="Blog information"),
		FieldPanel('intro'),
		FieldPanel('body'),
		InlinePanel('gallery_images', label="Gallery images"),
	]

	def get_context(self, request, *args, **kwargs):
		# Update context to include only published posts, ordered by reverse-chron
		context = super().get_context(request)
		blogpages = self.get_children().live().order_by('-first_published_at')
		context['blogpages'] = blogpages
		return context

class MarkdownBlogPage(Page):
	date = models.DateField("Post date")
	intro = models.CharField(max_length=250)
	body = MarkdownField(verbose_name="Content", blank=True)
	authors = ParentalManyToManyField('blog.authors', blank=True)
	tags = ClusterTaggableManager(through=MarkdownBlogPageTag, blank=True)

	def main_image(self):
		gallery_item = self.gallery_image.first()
		if gallery_item:
			return gallery_item.image
		else:
			return None

	search_fields = Page.search_fields + [
		index.SearchField('intro'),
		index.SearchField('body'),
	]

	content_panels = Page.content_panels + [
		MultiFieldPanel([
			FieldPanel('date'),
			FieldPanel('authors', widget=forms.CheckboxSelectMultiple),
			FieldPanel('tags'),
		], heading="Blog information"),
		FieldPanel('intro'),
		FieldPanel('body'),
		InlinePanel('mdgallery_images', label="MDGallery images"),
	]

	def get_context(self, request, *args, **kwargs):
		# Update context to include only published posts, ordered by reverse-chron
		context = super().get_context(request)
		blogpages = self.get_children().live().order_by('-first_published_at')
		context['blogpages'] = blogpages
		return context

class BlogPageGalleryImage(Orderable):
	page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name='gallery_images')
	image = models.ForeignKey(
		'wagtailimages.Image', on_delete=models.CASCADE, related_name='+'
	)
	caption = models.CharField(blank=True, max_length=250)

	panels = [
		FieldPanel('image'),
		FieldPanel('caption'),
	]

class MDBlogPageGalleryImage(Orderable):
	page = ParentalKey(MarkdownBlogPage, on_delete=models.CASCADE, related_name='mdgallery_images')
	image = models.ForeignKey(
		'wagtailimages.Image', on_delete=models.CASCADE, related_name='+'
	)
	caption = models.CharField(blank=True, max_length=250)

	panels = [
		FieldPanel('image'),
		FieldPanel('caption'),
	]

class BlogTagIndexPage(Page):
	def get_context(self, request):
		tag = request.GET.get('tag')
		blogpages = BlogPage.objects.filter(tags__name=tag)

		context = super().get_context(request)
		context['blogpages'] = blogpages
		return context
